<?php

namespace addons\facrm\library;


use app\admin\model\Admin;
use fast\Random;
use fast\Tree;
use think\Config;
use think\Db;

/**
 * 权限管理以及API接口类
 * Class Auth
 * @package addons\facrm\library
 */
class Auth extends \app\admin\library\Auth
{

    protected $_admin = null;
    protected $_token = '';
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 根据Token初始化
     *
     * @param string $token Token
     * @return boolean
     */
    public function init($token)
    {

        if ($this->logined)
        {
            return TRUE;
        }

        if ($this->_error){
			
		}
		$admin_id=cache('facrmapi'.$token);//解决多端登录频繁掉线问题
		$admin=$admin_id?Admin::get($admin_id):'';
		if (!$admin)
        {
           $admin = Admin::get(['token' => $token]);
        }
        if (!$admin)
        {
            $this->setError(('登录失效'));
            return FALSE;
        }

        if ($admin['status']=="hidden")
        {
            $this->setError(('帐户已锁定'));
            return FALSE;
        }


        if (Config::get('fastadmin.login_failure_retry') && $admin->loginfailure >= 10 && time() - $admin->updatetime < 86400) {
            $this->setError(("请在1天后重试"));
            return false;
        }
        $this->_admin=$admin;
        return true;

    }
    /**
     * 获取admin模型
     * @return Admin
     */
    public function getAdmin()
    {
        return $this->_admin;
    }

    /**
     * 兼容调用user模型的属性
     *
     * @param string $name
     * @return mixed
     */
    public function __get($name)
    {
        return $this->_admin ? $this->_admin->$name : null;
    }

    /**
     * 直接登录账号
     * @param int $admin_id
     * @return Admin
     */
    public function direct($admin_id)
    {

        if ($this->logined)
        {
            return TRUE;
        }

        $admin = Admin::get(['id' => $admin_id]);

        if (!$admin)
        {
            $this->setError("您没有登录");
            return FALSE;
        }

        if ($admin['status']=="hidden")
        {
            $this->setError("帐户已锁定");
            return FALSE;
        }


        if (Config::get('fastadmin.login_failure_retry') && $admin->loginfailure >= 10 && time() - $admin->updatetime < 86400) {
            $this->setError("请在1天后重试");
            return false;
        }
        $admin->loginfailure = 0;
        $admin->logintime = time();
        $admin->loginip = request()->ip();
        $admin->token = Random::uuid();
		cache('facrmapi'.$admin->token,$admin->id,86400);//解决多端登录频繁掉线问题
        $admin->save();
        $this->_admin=$admin;
		return $admin;

    }

    /**
     * 管理员登录
     *
     * @param string $username 用户名
     * @param string $password 密码
     * @param int    $keeptime 有效时长
     * @return  boolean
     */
    public function login($username, $password, $keeptime = 0)
    {
        $admin = Admin::get(['username' => $username]);
        if (!$admin) {
            $this->setError('用户名不正确');
            return false;
        }
        if ($admin['status'] == 'hidden') {
            $this->setError('管理员是被禁止的');
            return false;
        }
        if (Config::get('fastadmin.login_failure_retry') && $admin->loginfailure >= 10 && time() - $admin->updatetime < 86400) {
            $this->setError('请在1天后重试');
            return false;
        }
        if ($admin->password != md5(md5($password) . $admin->salt)) {
            $admin->loginfailure++;
            $admin->save();
            $this->setError('密码不正确');
            return false;
        }
        $admin->loginfailure = 0;
        $admin->logintime = time();
        $admin->loginip = request()->ip();
        $admin->token = Random::uuid();
		cache('facrmapi'.$admin->token,$admin->id,86400);//解决多端登录频繁掉线问题
        $admin->save();
        $this->_admin=$admin;
        $this->keeplogin($keeptime);
        return true;
    }

    /**
     * 检测是否登录
     *
     * @return boolean
     */
    public function isLogin()
    {
        if ($this->logined) {

            return true;
        }

        if ($this->_admin) {
            return true;
        }

        //判断管理员IP是否变动
        if (Config::get('fastadmin.loginip_check')) {
            if (!isset($this->_admin['loginip']) || $this->_admin['loginip'] != request()->ip()) {
                $this->logout();
                return false;
            }
        }
        $this->logined = false;
        return false;
    }

    /**
     * 退出登录
     */
    public function logout()
    {
        $admin = Admin::get(intval($this->id));
        if ($admin) {
            $admin->token = '';
            $admin->save();
        }
        $this->logined = false; //重置登录状态
        return true;
    }
	  /**
     * 获取指定组的员工[不含子组]
     * @param $admin_id
     * @return array|bool|string
     */
    public static function getGroupsAdminIds($groupids)
    {
        //获取当前部门负责人
        $adminIds = Db::name('auth_group_access')
            ->alias('ga')
            ->join('__'.strtoupper('admin').'__ a', 'ga.uid = a.id')
            ->where('ga.group_id','in',$groupids)
            ->where('a.status','normal')
            ->column('ga.uid');
        return $adminIds;
    }
    /**
     * 获取直接父IDS
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getParentAdminIds($uid)
    {
        $parentAdminIds = [];
        $groupIds = $this->getParentGroupIds($uid);
        $authGroupList = \app\admin\model\AuthGroupAccess::
        field('uid,group_id')
            ->where('group_id', 'in', $groupIds)
            ->select();
        foreach ($authGroupList as $k => $v) {
            $parentAdminIds[] = $v['uid'];
        }
        return $parentAdminIds;
    }

    /**
     * 取出当前管理员所有的父级组IDS
     * @return array
     */
    public function getParentGroupIds($uid)
    {
        //取出当前管理员所有的分组
        $groups = $this->getGroups($uid);

        $groupIds = [];
        foreach ($groups as $k => $v) {
            $groupIds[] = $v['id'];
        }

        $originGroupIds = $groupIds;
        foreach ($groups as $k => $v) {
            if (in_array($v['pid'], $originGroupIds)) {
                $groupIds = array_diff($groupIds, [$v['id']]);
                unset($groups[$k]);
            }
        }
        // 取出所有分组
        $groupList = \app\admin\model\AuthGroup::where(['status' => 'normal'])->select();
        $parentGroupIds=[];
        foreach ($groups as $k => $v) {
            // 取出包含自己的所有子节点
            $temp= Tree::instance()->init($groupList)->getParent($v['id'], true);
            if ($temp){
                foreach ($temp as $row) {
                    if (!in_array($row['id'],$parentGroupIds)){
                        $parentGroupIds[] = $row['id'];
                    }

                }
            }
        }
        return $parentGroupIds;
    }

    /**
     * 检查是否有客户的的权限
     * @param $customer 一个客户对象或客户ID
     * @param $auth 当前登录后台的权限对象
     * @param string $type 检查的类型 all：自己和下属的。owner：自己的，下属的：branch；
     * @return bool|int|string
     * @throws \think\Exception
     */
    public function checkCustomerAuth($customer,$auth,$type='all'){
        //超级管理员不做限制
        if ($auth->isSuperAdmin()) {
           return true;
        }
        switch ($type) {
            case 'all':
                //全部客户

                $childrenAdminIds = $auth->getChildrenAdminIds(true);
                if (!is_numeric($customer)&&isset($customer['owner_user_id'])){
                    //如果传过来的是客户对象
                    if (in_array($customer['owner_user_id'], $childrenAdminIds)){
                        return  true;
                    }
                    //是否有分享
                    if (in_array($auth->id, explode(',',$customer['rw_user_id']))){
                        return  true;
                    }
                }elseif(is_numeric($customer)){
                    $filter_w[] =function($q) use ($childrenAdminIds,$auth){
                        $q->where('owner_user_id','in', $childrenAdminIds)->whereOr('','exp',Db::raw("FIND_IN_SET('{$auth->id}',rw_user_id)"));
                    };

                }
                break;
            case "owner":

                if (!is_numeric($customer)&&isset($customer['owner_user_id'])){
                    //如果传过来的是客户对象
                    if ($customer['owner_user_id']== $auth->id){
                        return  true;
                    }
                    //是否有分享
                    if (in_array($auth->id, explode(',',$customer['rw_user_id']))){
                        return  true;
                    }
                }elseif(is_numeric($customer)){
                    $filter_w[] =function($q) use ($auth){
                        $q->where('owner_user_id',$auth->id)->whereOr('','exp',Db::raw("FIND_IN_SET('{$auth->id}',rw_user_id)"));
                    };
                }
                //我的客户
                break;
            case "branch":
                $childrenAdminIds = $auth->getChildrenAdminIds(false);
                //下属客户
                if (!is_numeric($customer)&&isset($customer['owner_user_id'])){
                    //如果传过来的是客户对象
                    if (in_array($customer['owner_user_id'], $childrenAdminIds)){
                        return  true;
                    }
                }elseif(is_numeric($customer)){
                    $filter_w['owner_user_id'] = ['in', $childrenAdminIds];
                }
                break;
            default://其它的还做TODO
                break;
        }
        if (is_numeric($customer)&&$filter_w){

            $customerModel= model('\app\admin\model\facrm\Customer');
            return $customerModel->where('id',$customer)->where($filter_w)->count();
        }

        return  false;

    }

    /**
     * 检查是否有线索的的权限
     * @param $customer 一个线索对象或客户ID
     * @param $auth 当前登录后台的权限对象
     * @param string $type 检查的类型 all：自己和下属的。owner：自己的，下属的：branch；
     * @return bool|int|string
     * @throws \think\Exception
     */
    public function checkCluesAuth($clues,$auth,$type='all'){
        //超级管理员不做限制
        if ($auth->isSuperAdmin()) {
            return true;
        }

        switch ($type) {
            case 'all':
                //全部
                $childrenAdminIds = $auth->getChildrenAdminIds(true);
                if (!is_numeric($clues)&&isset($clues['owner_user_id'])){
                    //如果传过来的是客户对象
                    if (in_array($clues['owner_user_id'], $childrenAdminIds)){
                        return  true;
                    }
                }elseif(is_numeric($clues)){

                    $filter_w['owner_user_id'] = ['in', $childrenAdminIds];
                }
                break;
            case "owner":

                if (!is_numeric($clues)&&isset($clues['owner_user_id'])){
                    //如果传过来的是客户对象
                    if ($clues['owner_user_id']== $auth->id){
                        return  true;
                    }
                }elseif(is_numeric($clues)){
                    $filter_w['owner_user_id'] = $auth->id;
                }
                //我的
                break;
            case "branch":
                $childrenAdminIds = $auth->getChildrenAdminIds(false);
                //下属
                if (!is_numeric($clues)&&isset($clues['owner_user_id'])){
                    //如果传过来的是客户对象
                    if (in_array($clues['owner_user_id'], $childrenAdminIds)){
                        return  true;
                    }
                }elseif(is_numeric($clues)){
                    $filter_w['owner_user_id'] = ['in', $childrenAdminIds];
                }
                break;
            default://其它的还做TODO
                break;
        }
        if (is_numeric($clues)&&isset($filter_w['owner_user_id'])){

            $cluesModel= model('\app\admin\model\facrm\Clues');
            return $cluesModel->where('id',$clues)->where($filter_w)->count();
        }

        return  false;

    }



    /**
     * 检查是否有商机的的权限
     * @param $business 一个商机对象或商机ID
     * @param $auth 当前登录后台的权限对象
     * @param string $type 检查的类型 all：自己和下属的。owner：自己的，下属的：branch；
     * @return bool|int|string
     * @throws \think\Exception
     */
    public function checkBusinessAuth($business,$auth,$type='all'){

        //超级管理员不做限制
        if ($auth->isSuperAdmin()) {
            return true;
        }

        switch ($type) {
            case 'all':
                //全部客户

                $childrenAdminIds = $auth->getChildrenAdminIds(true);

                if (!is_numeric($business)&&isset($business['owner_user_id'])){
                    //如果传过来的是客户对象
                    if (in_array($business['owner_user_id'], $childrenAdminIds)){
                        return  true;
                    }
                }elseif(is_numeric($business)){
                    $filter_w['owner_user_id'] = ['in', $childrenAdminIds];
                }
                break;
            case "owner":

                if (!is_numeric($business)&&isset($business['owner_user_id'])){
                    //如果传过来的是客户对象
                    if ($business['owner_user_id']== $auth->id){
                        return  true;
                    }
                }elseif(is_numeric($business)){
                    $filter_w['owner_user_id'] = $auth->id;
                }
                //我的客户
                break;
            case "branch":
                $childrenAdminIds = $auth->getChildrenAdminIds(false);
                //下属客户
                if (!is_numeric($business)&&isset($business['owner_user_id'])){
                    //如果传过来的是客户对象
                    if (in_array($business['owner_user_id'], $childrenAdminIds)){
                        return  true;
                    }
                }elseif(is_numeric($business)){
                    $filter_w['owner_user_id'] = ['in',$childrenAdminIds];
                }
                break;
            default://其它的还做TODO
                break;
        }
        if (is_numeric($business)&&isset($filter_w['owner_user_id'])){
            $businessModel= model('\app\admin\model\facrm\Business');
            return $businessModel->where('id',$business)->where($filter_w)->count();
        }

        return  false;

    }



}
